package com.mogu_soup.entity;

import java.awt.*;
import java.util.Vector;

import com.mogu_soup.game.GameFrame;
import com.mogu_soup.map.Brick;
import com.mogu_soup.util.BombPool;
import com.mogu_soup.util.BulletsPool;
import com.mogu_soup.util.Constant;
import com.mogu_soup.util.MyUtil;

import static com.mogu_soup.game.GameFrame.titleHeight;

/**
 * Version: 2.1
 * Author: TangJun
 * Date: 2024-08-02
 * Note: 坦克类，进行坦克的相关操作
 */
public class Tank extends Entity implements Runnable{
    //我方坦克图片
    private static final Image[] HERO = new Image[] {
            MyUtil.createImage("resource\\tank\\hero_up.gif"),
            MyUtil.createImage("resource\\tank\\hero_down.gif"),
            MyUtil.createImage("resource\\tank\\hero_left.gif"),
            MyUtil.createImage("resource\\tank\\hero_right.gif"),
    };

    public static final Image[] ENEMY = new Image[] {
            MyUtil.createImage("resource\\tank\\enemy_up.png"),
            MyUtil.createImage("resource\\tank\\enemy_down.png"),
            MyUtil.createImage("resource\\tank\\enemy_left.png"),
            MyUtil.createImage("resource\\tank\\enemy_right.png")
    };


    //坦克默认属性
    public static final int DEFAULT_SIZE = 80;
    private static final int DEFAULT_HP = 500;
    private static final int DEFAULT_SPEED = 10;
    private static final int ATK_MIN = 20;
    private static final int ATK_MAX = 100;
    private static final int ATK_CRITICAL_STRIKE = 200;


    private Vector<Bullet> bullets;//坦克子弹
    private Vector<Bomb> bombs;//坦克爆炸效果
    private BloodBar bloodBar;//血条
    private boolean isEnemy;//坦克类型
    private String name;//名字
    private Color color;//颜色

    //坦克初始化
    public Tank(int x, int y, int dir) {
        this.x = x;
        this.y = y;
        this.dir = dir;

        bullets = new Vector<Bullet>();
        bombs = new Vector<Bomb>();
        bloodBar = new BloodBar();

        speed = DEFAULT_SPEED;
        hp = DEFAULT_HP;
        size = DEFAULT_SIZE;

        isLive = true;
        isEnemy = true;

        name = MyUtil.getRandomName();
        color = MyUtil.getRandomColor();
    }

    //设置坦克属性
    public void set(int x, int y, int dir) {
        this.x = x;
        this.y = y;
        this.dir = dir;
        bullets = new Vector<Bullet>();
        speed = DEFAULT_SPEED;
        hp = DEFAULT_HP;
        isLive = true;
        size = DEFAULT_SIZE;
    }


    private int oldX = -1, oldY = -1;//记录上次移动的坐标，方便后退
    //坦克移动
    public void move() {
        oldX = x;
        oldY = y;
        switch (dir) {
            case DIR_UP:
                y -= speed;
                if (y < size / 2 + titleHeight) {
                    y = size / 2 + titleHeight;
                }
                break;
            case DIR_DOWN:
                y += speed;
                if (y > Constant.FRAME_HEIGHT - size / 2) {
                    y = Constant.FRAME_HEIGHT - size / 2;
                }
                break;
            case DIR_LEFT:
                if (x < size / 2) {
                    x = size / 2;
                }
                x -= speed;
                break;
            case DIR_RIGHT:
                x += speed;
                if (x > Constant.FRAME_HEIGHT - size / 2) {
                    x = Constant.FRAME_HEIGHT - size / 2;
                }
                break;
            default:
                break;
        }
    }
    private long lastFireTime = -1;//上一次开火时间
    //坦克开火
    public void fire() {
        if (System.currentTimeMillis() - lastFireTime < Constant.FIRE_INTERVAL){
            return;
        }
        lastFireTime = System.currentTimeMillis();//限制开火时间间隔
        Bullet bullet = BulletsPool.removeBullet();
        final int correction = 3;
        switch (dir) {
            case DIR_UP:
                bullet.setBullet(x, y - size / 2 + correction, dir, atk);
                break;
            case DIR_DOWN:
                bullet.setBullet(x, y + size / 2 - correction, dir, atk);
                break;
            case DIR_LEFT:
                bullet.setBullet(x - size / 2 + correction, y, dir, atk);
                break;
            case DIR_RIGHT:
                bullet.setBullet(x + size / 2 - correction, y, dir, atk);
                break;
            default:
                break;
        }
        new Thread(bullet).start();
        bullets.add(bullet);
    }


    //绘制操作
    @Override
    public void draw(Graphics g) {
        if (isEnemy) {
            g.drawImage(ENEMY[dir], x - size / 2, y - size / 2, size, size, null);//绘制敌方坦克
        } else {
            g.drawImage(HERO[dir], x - size / 2, y - size / 2, size, size, null);//绘制我方坦克
        }
        drawName(g);//绘制名字
        bloodBar.draw(g);//绘制血条
        drawBullets(g);//绘制子弹
        drawBombs(g);//绘制爆炸效果
    }

    //绘制名字
    private void drawName(Graphics g) {
        g.setColor(color);
        g.setFont(Constant.NAME_FONT);
        g.drawString(name, x - size / 2 - 10, y - size / 2 - 30);
    }

    //绘制子弹
    private void drawBullets(Graphics g) {
        for (int i = 0; i < bullets.size(); i++) {
            Bullet bullet = bullets.get(i);
            if (bullet.isLive) {
                bullet.draw(g);//绘制存活的子弹
            } else {
                BulletsPool.addBullet(bullets.remove(i));//移除销毁的子弹
                i--;
            }
        }
        //System.out.println("弹匣" + bullets.size());
    }

    //绘制爆炸效果
    private void drawBombs(Graphics g) {
        for (int i = 0; i < bombs.size(); i++) {
            Bomb bomb = bombs.get(i);
            if (bomb.isLive) {
                bomb.draw(g);//绘制未播放完的爆炸效果
            } else {
                BombPool.addBomb(bombs.remove(i));//移除已播放完的爆炸效果
                i--;
            }
        }
    }


    //与子弹碰撞
    public void collideBullets(Vector<Bullet> bullets) {
        for (Bullet bullet : bullets) {
            if (Entity.isCollideEntity(x, y, size, bullet.x, bullet.y, bullet.size, bullet.dir)) {
                bullet.isLive = false;//子弹消失
                //坦克扣血
                hurt();
                //产生爆炸效果
                Bomb bomb = BombPool.removeBomb();
                bomb.set(x, y, size);
                bombs.add(bomb);
            }
        }
    }

    //与坦克碰撞
    public void collideTanks(Vector<Tank> tanks) {
        for (Tank tank : tanks) {
            if (tank != this) {
                collideTank(tank);
            }
        }
    }

    //单个坦克与单个坦克碰撞
    public void collideTank(Tank tank) {
        if (Entity.isCollideEntity(tank.x, tank.y, tank.size, x, y, size - 1, dir)) {
            back();
        }
    }

    //与砖块碰撞
    public void collideBricks(Vector<Brick> bricks) {
        //看作移动的砖块碰静止的坦克
        for (Brick brick : bricks) {
            int type = brick.getType();
            //草块无碰撞体积
            if (type == Brick.IMAGE_GRASS) {
                continue;
            }
            int brickDir = -1;
            //相对运动
            if (this.dir % 2 == 0) {
                brickDir = this.dir + 1;
            } else {
                brickDir = this.dir - 1;
            }

            if (Entity.isCollideEntity(x, y, size, brick.x, brick.y, brick.size, brickDir)) {
                back();
            }
        }
    }

    private void back() {
        x = oldX;
        y = oldY;
    }

    //坦克扣血
    private void hurt() {
        //50%暴击率，否则攻击力：ATK_MIN~ATK_MAX
        if (Math.random() < Constant.CRITICAL_PROBABILITY) {
            atk = ATK_CRITICAL_STRIKE;
            bloodBar.isCriticalStrike = true;
        } else {
            atk = MyUtil.getRandomInt(ATK_MIN, ATK_MAX);
            bloodBar.isCriticalStrike = false;
        }
        hp -= atk;
        //血量小于0，坦克销毁
        if (hp < 0) {
            die();
        }
    }

    //坦克死亡
    private void die() {
        if (isEnemy) {
            isLive = false;
        } else {
            //修改游戏状态为结束
            GameFrame.setGameState(Constant.STATE_OVER);
        }
    }

    //归还子弹对象
    public void ReturnBullets() {
        for (Bullet bullet : bullets) {
            BulletsPool.addBullet(bullet);
        }
        bullets.clear();
    }
    //归还爆炸对象
    public void ReturnBombs() {
        for (Bomb bomb : bombs) {
            BombPool.addBomb(bomb);
        }
        bombs.clear();
    }
    //血条类
    class BloodBar{
        public static final int BAR_LENGTH = 100;//血条长度
        public static final int BAR_HEIGHT = 8;//血条高度
        private boolean isCriticalStrike;
        public void draw(Graphics g) {
            //绘制边框
            g.setColor(Color.black);
            g.drawRect(x - size / 2 - 10, y - size / 2 - 20, BAR_LENGTH, BAR_HEIGHT);
            //绘制底色
            g.setColor(Color.gray);
            g.fillRect(x - size / 2 - 10, y - size / 2 - 20, BAR_LENGTH, BAR_HEIGHT);
            //绘制暴击提示
            if (isCriticalStrike) {
                g.setColor(Color.red);
                g.setFont(Constant.HINT_FONT);
                g.drawString(Constant.CRITICAL_STRIKE, x - size / 2 + BAR_LENGTH, y - size / 2 - 10);
            }
            //绘制血量,我方绿色，敌方红色
            if (!isEnemy) {
                g.setColor(Color.green);
            } else {
                g.setColor(Color.red);
            }
            g.fillRect(x - size / 2 - 10, y - size / 2 - 20, BAR_LENGTH * hp / DEFAULT_HP, BAR_HEIGHT);
        }
    }

    public boolean isEnemy() {
        return isEnemy;
    }

    public void setEnemy(boolean enemy) {
        isEnemy = enemy;
    }

    public int getDir() {
        return dir;
    }

    public void setDir(int dir) {
        this.dir = dir;
    }

    public Vector<Bullet> getBullets() {
        return bullets;
    }
    //坦克的AI程序
    @Override
    public void run() {
        long directionTime = 0;
        while (isLive) {
            //每隔一定时间就变向
            if (System.currentTimeMillis() - directionTime > Constant.ENEMY_DIRECTION_INTERVAL) {
                dir = MyUtil.getRandomInt(DIR_UP, DIR_RIGHT + 1);
                directionTime = System.currentTimeMillis();
            }
            move();//移动
            //开火
            if (Math.random() < Constant.ENEMY_FIRE_PROBABILITY) {
                fire();
            }
            try {
                Thread.sleep(Constant.ENEMY_MOVE_INTERVAL);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
